package com.jrsoft.bim.util;

import com.alibaba.fastjson.JSON;
import com.jrsoft.bim.component.poi.ExcelUtil;
import com.jrsoft.bim.db.ConnDB;
import com.jrsoft.bim.db.DBUtil;
import com.jrsoft.bim.dto.*;
import com.jrsoft.bim.dto.excel.ComponentDTO;
import com.jrsoft.bim.dto.excel.FieldDTO;
import com.jrsoft.bim.enums.ComponentCategoryEnum;
import com.jrsoft.bim.util.math.Line;
import com.jrsoft.bim.util.math.Point;
import org.springframework.beans.BeanUtils;
import org.springframework.core.io.ClassPathResource;
import org.sqlite.SQLiteException;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.*;

/**
 * ${DESCRIPTION}
 *
 * @author Blueeyedboy
 * @create 2019-12-20 5:34 PM
 **/
public class ConvertUtil {

	public static DBUtil dbUtil = null;

	public static void convert(String srcPath, String descFilePath){

		Map<ComponentCategoryEnum,List<ComponentDTO>> result = ExcelUtil.parse(srcPath);
//		System.out.println("-----result-----"+JSON.toJSONString(result));
		File f = null;
		if(descFilePath.endsWith(".ydb")){
			f = new File(descFilePath);
		}else{
			f = new File(descFilePath + File.separator + DateUtil.getTimeMillis()+".ydb" );
		}
		if(f.exists()){
			f.deleteOnExit();
		}
		try {
//			File demo = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + "demo.ydb");

			ClassPathResource resource = new ClassPathResource("demo-yjk.ydb");
//			File demo = resource.getFile();
//			System.out.println(demo.getAbsolutePath()+"--------"+f.getAbsolutePath());

			FileUtil.copyFile(resource.getInputStream(),new FileOutputStream(f));
			String dbPath = f.getAbsolutePath();
			ConnDB db = new ConnDB("jdbc:sqlite:"+dbPath,"","");
			dbUtil = new DBUtil(db);
			/*Vector<Map<String,Object>> data = db.getData(" select name from sqlite_master where type = 'table'");
			Optional.ofNullable(data).ifPresent(System.out::println);*/
			StringBuilder sql = new StringBuilder();
			// 先解析柱子数据
			List<ComponentDTO> pillarList = result.get(ComponentCategoryEnum.PILLAR);
			// 定义楼层
			Map<String,Map<String,String>> tblFloor = new HashMap<>();
			//
			Map<String,Map<String,String>> tblStdFlr = new HashMap<>();
			// 定义坐标点
			Map<String,Map<String,String>> tblJoint = new HashMap<>();
			// 定义柱子类型
			Map<String,Map<String,String>> tblColSect = new HashMap<>();
			// 定义梁类型
			Map<String,Map<String,String>> tblbeamSect = new HashMap<>();
			// 定义板类型
			Map<String,Map<String,String>> tblSlab = new HashMap<>();

			// 定义每一层轴网数据
			Map<String,List<JointDTO>> jointData = new HashMap<>();
			// 定义每一层次梁跟轴网交点
			Map<String,List<JointDTO>> beamCrossPointData = new HashMap<>();
			// 定义每一层axis数据
			Map<String,List<AxisDTO>> axisData = new HashMap<>();
			// 定义每一层轴网数据
			Map<String,List<GridDTO>> gridData = new HashMap<>();
			// 定义每一层楼层数据
			Map<String,FloorDTO> floorData = new HashMap<>();
			// 定义每一层柱子数据
			Map<String,List<ColSegDTO>> colSegData = new HashMap<>();
			// 定义每一层梁数据
			Map<String,List<BeamSegDTO>> beamSegData = new HashMap<>();


			/*// 记录每一层层高
			Map<Integer,Double> levelHeight = new HashMap<>();*/
			int id = 1000;
			Integer tbLFloorIndex = null;
			int tbLGridIndex = 0;
			int tbLAxisIndex = 0;
			int tblStdFlrIndex = 0;
			int tblJointIndex = 0;
			int tblColSegIndex = 0;
			int tblColSectIndex = 0;
			String level = null;
//			System.out.println("----pillarList----"+ JSON.toJSONString(pillarList));
			System.out.println("---------开始分析柱子---------");
			if(pillarList != null){
				StringBuilder tblFloorSql = new StringBuilder();
				StringBuilder tblStdSql = new StringBuilder();
				for(ComponentDTO c : pillarList){
					// 构件定位点坐标X1
					FieldDTO field_x1 = c.getFieldDTOMap().get("KZ021");
					// 构件定位点坐标Yw
					FieldDTO field_yw = c.getFieldDTOMap().get("KZ022");
					// 构件定位点坐标z
					FieldDTO field_z = c.getFieldDTOMap().get("KZ023");
					// 方向角β
					FieldDTO field_B = c.getFieldDTOMap().get("KZ024");
					// 柱高h1
					FieldDTO field_h1 = c.getFieldDTOMap().get("KZ027");
					// 柱截面边长a
					FieldDTO field_a = c.getFieldDTOMap().get("KZ025");
					// 柱截面边长b
					FieldDTO field_b = c.getFieldDTOMap().get("KZ026");
					if(field_z != null && field_h1 != null){
						String levelBStr = field_z.getValue();
						String heightStr = field_h1.getValue();
						if(StringUtil.isNotBlank(levelBStr) && StringUtil.isNotBlank(heightStr)){
							double x = Double.parseDouble(field_x1.getValue())*1000;
							double y = Double.parseDouble(field_yw.getValue())*1000;
							double z = Double.parseDouble(field_z.getValue())*1000;
							double β = Double.parseDouble(field_B.getValue());
							double a = Double.parseDouble(field_a.getValue());
							double b = Double.parseDouble(field_b.getValue());
							double levelB = z;
							double height = Double.parseDouble(heightStr);
							String aStr = field_a.getValue();
							String bStr = field_b.getValue();

							Integer levelInt = getLevelByCode(c.getCode());
							System.out.println(c.getCode()+"------levelInt-------"+levelInt);
							if(tbLFloorIndex == null){
								tbLFloorIndex = levelInt;
							}else{
								if(levelInt>tbLFloorIndex){
									tbLFloorIndex = levelInt;
								}
							}
							level = levelInt.toString();
							StdFlrDTO stdFlrDTO = null;
							FloorDTO floorDTO = null;
							if(floorData.containsKey(level)){
								floorDTO = floorData.get(level);
								stdFlrDTO = floorDTO.getStdFlrDTO();
							}else{
								stdFlrDTO = StdFlrDTO.builder()
										.id(++id)
										.no(levelInt)
										.level(tbLFloorIndex)
										.height(height)
										.build();

								floorDTO = FloorDTO.builder()
										.id(++id)
										.no(levelInt)
										.level(tbLFloorIndex)
										.levelB(levelB)
										.height(height)
										.z(levelB+height)
										.build();

								floorDTO.setStdFlrDTO(stdFlrDTO);
								floorData.put(level,floorDTO);

								dbUtil.insertTblFloor(floorDTO);
								dbUtil.insertTblStdFlr(stdFlrDTO);
							}

							// 计算柱子四个边角的坐标 , 默认从左下角，左上角，右上角，右下角顺序计算
							PointDTO p1 = PointDTO.builder()
									.x(x)
									.y(y-a/2)
									.build();
							PointDTO p2 = PointDTO.builder()
									.x(x)
									.y(y+a/2)
									.build();
							PointDTO p3 = PointDTO.builder()
									.x(x+a)
									.y(y+a/2)
									.build();
							PointDTO p4 = PointDTO.builder()
									.x(x+a)
									.y(y-a/2)
									.build();

							ColSegDTO segDto = ColSegDTO.builder()
									.code(c.getCode())
									.x(x)
									.y(y)
									.z(z)
									.angle(β)
									.a(a)
									.b(b)
									.l(height)
									.id(++id)
									.no(++tblColSegIndex)
									.level(levelInt)
									.p1(p1)
									.p2(p2)
									.p3(p3)
									.p4(p4)
									.floorDTO(floorDTO)
									.stdFlrDTO(stdFlrDTO)
									.build();


							// 表示第一层
							if(z == 0){
								String firstLevel = "1";
								List<JointDTO> gridPointData = jointData.get(firstLevel);
								if(gridPointData == null){
									gridPointData = new ArrayList<>();
									jointData.put(firstLevel, gridPointData);
								}
//								System.out.println(Math.toRadians(β)+"-----"+β+"-------"+Math.sin(Math.toRadians(β)));
								/*PointDTO p = PointDTO.builder()
										.x(x+Math.cos(Math.toRadians(β))*(a/2))
										.y(y+Math.sin(Math.toRadians(β))*(a/2))
										.build();*/

								JointDTO joint = JointDTO.builder()
										.x(x+Math.cos(Math.toRadians(β))*(a/2))
										.y(y+Math.sin(Math.toRadians(β))*(a/2))
										.colSegX(x)
										.colSegY(y)
										.level(levelInt)
										.id(++id)
										.floorDTO(floorDTO)
										.stdFlrDTO(stdFlrDTO)
										.build();

								// 记录每一层的点
								gridPointData.add(joint);

								segDto.setJointDTO(joint);
								// 默认第一层偏移量都是0
								segDto.setEccX(0d);
								segDto.setEccY(0d);


							}

							List<ColSegDTO> colSegDTOS = colSegData.get(level);
							if(colSegDTOS == null){
								colSegDTOS = new ArrayList<>();
								colSegData.put(String.valueOf(level),colSegDTOS);
							}
							colSegDTOS.add(segDto);
							String tblColSectKey = aStr+bStr;
							if(!tblColSect.containsKey(tblColSectKey)){

								// 处理tblColSect
								Map<String,String> tblColSectObj = new HashMap<>();
								tblColSectIndex++;
								tblColSectObj.put("ID",String.valueOf(++id));
								tblColSectObj.put("No_",String.valueOf(tblColSectIndex));
								tblColSectObj.put("Name","''");
								tblColSectObj.put("Mat","6");
								tblColSectObj.put("Kind","1");
								tblColSectObj.put("ShapeVal","'1,"+a+","+b+",6,"+tblColSectObj.get("ID")+",'");
								tblColSectObj.put("ShapeVal1","''");
								tblColSect.put(tblColSectKey, tblColSectObj);

								StringBuilder tblColSectSql = new StringBuilder();
								tblColSectSql.append("insert into tblColSect(ID,No_,Name,Mat,Kind,ShapeVal,ShapeVal1)values(")
										.append(tblColSectObj.get("ID"))
										.append(",").append(tblColSectObj.get("No_"))
										.append(",").append(tblColSectObj.get("Name"))
										.append(",").append(tblColSectObj.get("Mat"))
										.append(",").append(tblColSectObj.get("Kind"))
										.append(",").append(tblColSectObj.get("ShapeVal"))
										.append(",").append(tblColSectObj.get("ShapeVal1"))
										.append(");");
								db.executeUpdateSql(tblColSectSql.toString());

								segDto.setSectID(Integer.parseInt(tblColSectObj.get("ID")));
							}else{
								Map<String,String> tblColSectObj = tblColSect.get(tblColSectKey);
								segDto.setSectID(Integer.parseInt(tblColSectObj.get("ID")));
							}
							// 表示第一层
							if(z == 0) {
								dbUtil.insertTblColSeg(segDto);
							}


						}

					}
				}
			}
			// 如果存在多层,因为轴网坐标每层都一样，所以需要拷贝第一层数据到其它层
//			System.out.println("-------------"+tbLFloorIndex);
//			System.out.println(tbLFloorIndex+"-------------"+JSON.toJSONString(jointData));
			if(tbLFloorIndex>1){
				List<JointDTO> data = jointData.get("1");
				for(int i = 2;i<=tbLFloorIndex;i++){
					List<JointDTO> tempList = JSON.parseArray(JSON.toJSONString(data),JointDTO.class);
					FloorDTO floorDTO = floorData.get(String.valueOf(i));
					for(JointDTO j: tempList){
						j.setId(++id);
						j.setLevel(i);
						j.setFloorDTO(floorDTO);
						j.setStdFlrDTO(floorDTO.getStdFlrDTO());
					}



					jointData.put(String.valueOf(i), tempList);
				}
			}
			// 循环插入柱子
			for(int i = 2;i<=tbLFloorIndex;i++) {
				// 获取第二层的柱子
				// 查找第一层轴网所有点，查找最近带你，然后计算便宜,因为在盈建科，第一层柱子跟轴网重复，但是在cdm是有便宜，所以其它层柱子便宜对比第一层计算
				List<ColSegDTO> colSegDTOData = colSegData.get(String.valueOf(i));
				FloorDTO floorDTO = floorData.get(String.valueOf(i));
				tblColSegIndex = 0;

				for(ColSegDTO segDto : colSegDTOData){
					List<JointDTO> data = jointData.get(String.valueOf(i));
					double minDistince = 0;
					JointDTO minJoint = null;
					for(JointDTO p : data){
						double tempMinDistance = MathUtil.getDistance(new Point(segDto.getX(),segDto.getY()),new Point(p.getX(),p.getY()));
						if(minJoint == null){
							minJoint = p;
							minDistince = tempMinDistance;
						}else{
							if(tempMinDistance<minDistince){
								minDistince = tempMinDistance;
								minJoint = p;

							}
						}
					}
					segDto.setId(++id);
					segDto.setNo(++tblColSegIndex);
					segDto.setJointDTO(minJoint);
					segDto.setFloorDTO(floorDTO);
					segDto.setStdFlrDTO(floorDTO.getStdFlrDTO());
//					System.out.println(segDto.getX()+","+segDto.getY()+"--------"+minDistince+"---------"+minJoint);
					double eccX = 0;
					double eccY = 0;
					if(minDistince !=0){
						eccX = minJoint.getColSegX()-segDto.getX();
						eccY = segDto.getY()-minJoint.getColSegY();


					}
					segDto.setEccX(eccX);
					segDto.setEccY(eccY);

					dbUtil.insertTblColSeg(segDto);
				}

			}
//			System.out.println("---------层---------"+tbLFloorIndex);
			// 计算axis数据
			for(int i = 1;i<=tbLFloorIndex;i++){
				List<JointDTO> data = jointData.get(String.valueOf(i));
				FloorDTO floorDTO = floorData.get(String.valueOf(i));

				//				System.out.println("---------层---------"+i);
				int tblAxisNo = 0;
				for(int m = 0;m<data.size();m++){
					JointDTO p1 = data.get(m);
					p1.setNo(m+1);
					Point pt1 = new Point(p1.getX(),p1.getY());
					JointDTO minXPoint = null;
					JointDTO minYPoint = null;
					double minXDinstance = 0;
					double minYDinstance = 0;
					for(int n = m+1;n<data.size();n++) {
						JointDTO p2 = data.get(n);
						if(MathUtil.compareDouble(p1.getX(),p2.getX()) == 0 && MathUtil.compareDouble(p1.getY(),p2.getY()) == 0){
							continue;
						}
						// 只算正向坐标和
						if((p1.getX() - p2.getX() == 0 && p2.getY()>p1.getY()) || (p1.getY() - p2.getY() == 0 && p2.getX()>p1.getX())){
//							if((p1.getX() - p2.getX() == 0 && p2.getY()>p1.getY()) || (p1.getY() - p2.getY() == 0 && p2.getX()>)){
								//还要计算最短距离的点
							double minTempDistance = MathUtil.getDistance(pt1,new Point(p2.getX(),p2.getY()));
							// 判断都是y轴的点
							if((p1.getX() - p2.getX()) == 0){
								if(minYPoint == null){
									minYPoint = p2;
									minYDinstance = minTempDistance;
								}else{
									if(minTempDistance < minYDinstance){
										minYDinstance = minTempDistance;
										minYPoint = p2;
									}
								}
							}
							// 判断都是x轴的点
							if((p1.getY() - p2.getY()) == 0){
								if(minXPoint == null){
									minXPoint = p2;
									minXDinstance = minTempDistance;
								}else{
									if(minTempDistance < minXDinstance){
										minXDinstance = minTempDistance;
										minXPoint = p2;
									}
								}
							}

						}
					}
					if(minXPoint != null){
						AxisDTO axisDTO = AxisDTO.builder()
								.id(++id)
								.no(++tblAxisNo)
								.start(p1)
								.end(minXPoint)
								.level(i)
								.floorDTO(floorDTO)
								.stdFlrDTO(floorDTO.getStdFlrDTO())
								.build();

						//							System.out.println(p1.getX()+","+p1.getY()+"---------AxisDTO----"+axisDTO.getNo()+"-----"+p2.getX()+","+p2.getY());
						// 存储每一层的axis
						List<AxisDTO> axisDTOS = axisData.get(String.valueOf(i));
						if(axisDTOS == null){
							axisDTOS = new ArrayList<>();
							axisData.put(String.valueOf(i),axisDTOS);
						}
						axisDTOS.add(axisDTO);
					}
					if(minYPoint != null){
						AxisDTO axisDTO = AxisDTO.builder()
								.id(++id)
								.no(++tblAxisNo)
								.start(p1)
								.end(minYPoint)
								.level(i)
								.floorDTO(floorDTO)
								.stdFlrDTO(floorDTO.getStdFlrDTO())
								.build();

						//							System.out.println(p1.getX()+","+p1.getY()+"---------AxisDTO----"+axisDTO.getNo()+"-----"+p2.getX()+","+p2.getY());
						// 存储每一层的axis
						List<AxisDTO> axisDTOS = axisData.get(String.valueOf(i));
						if(axisDTOS == null){
							axisDTOS = new ArrayList<>();
							axisData.put(String.valueOf(i),axisDTOS);
						}
						axisDTOS.add(axisDTO);
					}
				}



			}
//			System.out.println("--------gridPoints--------"+JSON.toJSONString(jointData));
//			System.out.println("--------axisData--------"+JSON.toJSONString(axisData));

			// 解析梁数据
			System.out.println("---------开始分析梁---------");
			// 记录次梁与跨梁交点
			Map<String,Map<String,JointDTO>> jointDTOMap = new HashMap<>();
			int tblBeamIndex = 0;
			List<ComponentDTO> bridgeList = result.get(ComponentCategoryEnum.BRIDGE);
//			System.out.println("----bridgeList----"+ JSON.toJSONString(bridgeList));
			if(bridgeList != null){
				for(ComponentDTO c : bridgeList){
//					System.out.println(c.getCode()+"-------分析-------"+JSON.toJSONString(c));
					// 构件定位点坐标X1
					FieldDTO field_x = c.getFieldDTOMap().get("KL021");
					// 构件定位点坐标Yw
					FieldDTO field_y = c.getFieldDTOMap().get("KL022");
					// 构件定位点坐标z
					FieldDTO field_z = c.getFieldDTOMap().get("KL023");
					// 方向角β
					FieldDTO field_B = c.getFieldDTOMap().get("KL024");
					// 梁长
					FieldDTO field_l = c.getFieldDTOMap().get("KL025");
					// 梁宽
					FieldDTO field_w = c.getFieldDTOMap().get("KL026");
					// 梁高
					FieldDTO field_h = c.getFieldDTOMap().get("KL027");

					if(field_w != null && field_h != null) {
						String weightStr = field_w.getValue();
						String heightStr = field_h.getValue();
						if (StringUtil.isNotBlank(weightStr) && StringUtil.isNotBlank(heightStr)) {
							double x = Double.parseDouble(field_x.getValue())*1000;
							double y = Double.parseDouble(field_y.getValue())*1000;
							double z = Double.parseDouble(field_z.getValue())*1000;
							double β = Double.parseDouble(field_B.getValue());
							double l = Double.parseDouble(field_l.getValue());
							double w = Double.parseDouble(field_w.getValue());
							double h = Double.parseDouble(field_h.getValue());


//							Integer leveInt = 1;
							// 先计算是哪一层
							/*for(Map.Entry<String,FloorDTO> floor : floorData.entrySet()){
								// 判断是否梁的标高加高度 = 楼层的标高
								if((floor.getValue().getZ() - z - h) == 0){
									leveInt = Integer.parseInt(floor.getKey());
									break;
								}
							}*/
							Integer leveInt = getLevelByCode(c.getCode());
							leveInt = leveInt-1;
							level = leveInt.toString();
//							System.out.println(c.getCode()+"----------------"+level);
							// 获取该楼层所有相关柱子
							List<ColSegDTO> colSegDTOList = colSegData.get(level);
							FloorDTO floorDTO = floorData.get(level);

							if(colSegDTOList == null){
								continue;
							}
							// 判断是否跨梁，如果是跨梁，则跨梁的坐标点应该在某个柱子的四边上
							boolean isSpanBeam = false;
							for(ColSegDTO colSeg : colSegDTOList){
								if(MathUtil.isPointInRectangle(new PointDTO(x,y), new PointDTO[]{colSeg.getP1(),colSeg.getP2(),colSeg.getP3(),colSeg.getP4()})){
									isSpanBeam = true;
									break;
								}
							}
//							System.out.println(c.getCode()+"-----"+isSpanBeam);
							// 梁起始中心点坐标 ，采取从线左侧到右侧，下到上
							PointDTO p1 = new PointDTO();
							// 梁尾中心点坐标
							PointDTO p2 = new PointDTO();
							if(β == 0){
								p1.setX(x);
								p1.setY(y);
								p2.setX(x+l);
								p2.setY(y);
							}else if(β == 90){
								p1.setX(x);
								p1.setY(y);
								p2.setX(x);
								p2.setY(y+l);
							}

							BeamSegDTO beamSeg = BeamSegDTO.builder()
									.code(c.getCode())
									.id(++id)
									.x(x)
									.y(y)
									.z(z)
									.angle(β)
									.l(l)
									.w(w)
									.h(h)
									.start(p1)
									.end(p2)
									.floorDTO(floorDTO)
									.stdFlrDTO(floorDTO.getStdFlrDTO())
									.build();

							if(isSpanBeam){
								// 计算跨梁start,end断点坐标就是轴网坐标
								beamSeg.setSpan(true);
							}else{
								// 计算次梁start,end断点坐标就是轴网坐标
								beamSeg.setSpan(false);
								// 次梁的两个断点是轴网的节点
								Point pt1 = null;
								Point pt2 = null;
								double minDistance1 = 0;
								double minDistance2 = 0;
								// 需要循环每个axis数据，计算交点，并且计算出跟次梁两端点最近的点作为轴网节点
								List<AxisDTO> axisDTOS = axisData.get(level);
								for(AxisDTO axisDTO : axisDTOS){
									Point point = MathUtil.getLineCrossPoint(new Point(p1.getX(),p1.getY()),
											new Point(p2.getX(),p2.getY()),
											new Point(axisDTO.getStart().getX(),axisDTO.getStart().getY()),
											new Point(axisDTO.getEnd().getX(),axisDTO.getEnd().getY())
									);
//									System.out.println(p1+"---------1---------"+p2);
//									System.out.println(axisDTO.getStart()+"---------2---------"+axisDTO.getEnd());
//									System.out.println("---------交点---------"+point);
									if(point != null){
										double minDistanceTemp1 = MathUtil.getDistance(point,new Point(p1.getX(),p1.getY()));
										double minDistanceTemp2 = MathUtil.getDistance(point,new Point(p2.getX(),p2.getY()));

//										System.out.println(minDistanceTemp1+"-----------------"+minDistanceTemp2);

										if(pt1 == null){
											pt1 = point;
											pt2 = point;
											minDistance1 = minDistanceTemp1;
											minDistance2 = minDistanceTemp2;
										}else{
											if(minDistanceTemp1<minDistance1){
												minDistance1 = minDistanceTemp1;
												pt1 = point;
											}
											if(minDistanceTemp2<minDistance2){
												minDistance2 = minDistanceTemp2;
												pt2 = point;
											}
										}
									}
								}

//								System.out.println(pt1+"---------最终交点---------"+pt2);
								List<JointDTO> beamCrossPointList = beamCrossPointData.get(level);
								if(beamCrossPointList == null){
									beamCrossPointList = new ArrayList<>();
									beamCrossPointData.put(level,beamCrossPointList);
								}
								List<JointDTO> data = jointData.get(level);
								String key1 = pt1.getX()+"-"+pt2.getY();
								JointDTO j1 = null;
								JointDTO j2 = null;
								// 判断该点是否之前存在
								Map<String,JointDTO> jointDTOMapData = jointDTOMap.get(level);
								if(jointDTOMapData == null){
									jointDTOMapData = new HashMap<>();
									jointDTOMap.put(level,jointDTOMapData);
								}
								if(jointDTOMapData.containsKey(key1)){
									j1 = jointDTOMapData.get(key1);
								}else{
									j1 = new JointDTO();
									BeanUtils.copyProperties(pt1,j1);
									j1.setId(++id);
									j1.setNo(data.size()+1);
									j1.setLevel(Integer.parseInt(level));
									j1.setFloorDTO(floorDTO);
									j1.setStdFlrDTO(floorDTO.getStdFlrDTO());
									data.add(j1);
									jointDTOMapData.put(key1,j1);
									beamCrossPointList.add(j1);

								}

								String key2 = pt2.getX()+"-"+pt2.getY();
								if(jointDTOMapData.containsKey(key2)){
									j2 = jointDTOMapData.get(key2);
								}else{
									j2 = new JointDTO();
									BeanUtils.copyProperties(pt2,j2);
									j2.setId(++id);
									j2.setNo(data.size()+1);
									j2.setLevel(Integer.parseInt(level));
									j2.setFloorDTO(floorDTO);
									j2.setStdFlrDTO(floorDTO.getStdFlrDTO());
									data.add(j2);
									jointDTOMapData.put(key2,j2);
									beamCrossPointList.add(j2);
								}



								//							System.out.println(p1.getX()+","+p1.getY()+"---------AxisDTO----"+axisDTO.getNo()+"-----"+p2.getX()+","+p2.getY());

								AxisDTO axisDTO = AxisDTO.builder()
										.id(++id)
										.no(axisDTOS.size()+1)
										.start(j1)
										.end(j2)
										.level(j1.getLevel())
										.secondaryBeam(true)
										.floorDTO(floorDTO)
										.stdFlrDTO(floorDTO.getStdFlrDTO())
										.build();
								axisDTOS.add(axisDTO);

							}
							List<BeamSegDTO> beamSegDTOS = beamSegData.get(level);
							if(beamSegDTOS == null){
								beamSegDTOS = new ArrayList<>();
								beamSegData.put(level,beamSegDTOS);
							}
							beamSegDTOS.add(beamSeg);
							String tblBeamKey = weightStr+"-"+heightStr;
							if(!tblbeamSect.containsKey(tblBeamKey)){
								// 处理tblColSect
								Map<String,String> obj = new HashMap<>();
								tblBeamIndex++;
								obj.put("ID",String.valueOf(++id));
								obj.put("No_",String.valueOf(tblBeamIndex));
								obj.put("Name","''");
								obj.put("Mat","6");
								obj.put("Kind","1");
								obj.put("ShapeVal","'1,"+weightStr+","+heightStr+",6,"+obj.get("ID")+",'");
								obj.put("ShapeVal1","''");
								tblbeamSect.put(tblBeamKey, obj);

								StringBuilder tblColSectSql = new StringBuilder();
								tblColSectSql.append("insert into tblBeamSect(ID,No_,Name,Mat,Kind,ShapeVal,ShapeVal1)values(")
										.append(obj.get("ID"))
										.append(",").append(obj.get("No_"))
										.append(",").append(obj.get("Name"))
										.append(",").append(obj.get("Mat"))
										.append(",").append(obj.get("Kind"))
										.append(",").append(obj.get("ShapeVal"))
										.append(",").append(obj.get("ShapeVal1"))
										.append(");");
								db.executeUpdateSql(tblColSectSql.toString());
								beamSeg.setBeamSect(Integer.parseInt(obj.get("ID")));
							}else{
								Map<String,String> obj = tblbeamSect.get(tblBeamKey);
								beamSeg.setBeamSect(Integer.parseInt(obj.get("ID")));
							}
						}
					}
				}
			}


//			System.out.println("--------gridPoints--------"+JSON.toJSONString(jointData));
//			System.out.println("--------axisData--------"+JSON.toJSONString(axisData));
//			System.out.println("--------beamSegData--------"+JSON.toJSONString(beamSegData));

			// 插入tblJoint
			for(Map.Entry<String,List<JointDTO>> entry : jointData.entrySet()){
				level = entry.getKey();
				List<JointDTO> data = entry.getValue();
				for(JointDTO item : data){
					dbUtil.insertTblJoint(item);
				}
			}

			// 插入tblAxis数据，顺便计算grid数据
			for(Map.Entry<String,List<AxisDTO>> axisEntry : axisData.entrySet()){
				level = axisEntry.getKey();
//				System.out.println("-----------"+level+"----------");
				List<AxisDTO> data = axisEntry.getValue();
				List<JointDTO> beamCrossPointList = beamCrossPointData.get(level);
				FloorDTO floorDTO = floorData.get(level);

//				System.out.println("-----beamCrossPointList------"+beamCrossPointList);
				List<GridDTO> gridDTOList = gridData.get(level);
				if(gridDTOList == null){
					gridDTOList = new ArrayList<>();
					gridData.put(level,gridDTOList);
				}
				int tblBeamNo = 0;
				for(AxisDTO item : data){
					dbUtil.insertTblAxis(item);
					// 判断是否平行，
					Line axisLine = MathUtil.getLine(new Point(item.getStart().getX(),item.getStart().getY()),new Point(item.getEnd().getX(),item.getEnd().getY()));
					Double axisLineSlope = MathUtil.getLineSlope(axisLine.getStart(),axisLine.getEnd());

					// 计算梁的偏移量,上正下负,左正右负
					double ecc = 0;
					// 计算最近的梁
					BeamSegDTO beamSeg = null;
					List<BeamSegDTO> beamSegDTOS = beamSegData.get(level);
					// 循环查找最近的平行梁
					if(beamSegDTOS != null && beamSegDTOS.size()>0){
						for(BeamSegDTO beamSegDTO : beamSegDTOS){

							Line beamLine = MathUtil.getLine(new Point(beamSegDTO.getStart().getX(),beamSegDTO.getStart().getY()),new Point(beamSegDTO.getEnd().getX(),beamSegDTO.getEnd().getY()));
							Double beamLineSlope = MathUtil.getLineSlope(beamLine.getStart(),beamLine.getEnd());

							// 判断是否平行线
							if(MathUtil.isParallelLines(axisLineSlope ,beamLineSlope)){
								// 计算平行线之间距离,只需要计算其中一个点到线的距离
								double tempEcc = MathUtil.getLineDistince(axisLine,beamLine.getStart());
								if(beamSeg == null){
									beamSeg = beamSegDTO;
									ecc = tempEcc;
								}else{
									if(tempEcc<ecc){
										ecc = tempEcc;
										beamSeg = beamSegDTO;
									}
								}
							}else{
								continue;
							}

						}
					}
					if(ecc !=0){
						// 如果是平行x轴
						if(beamSeg.getAngle() == 0){
							if(beamSeg.getY()<axisLine.getStart().getY()){
								ecc = -ecc;
							}
						}else if(beamSeg.getAngle() == 90){
							if(beamSeg.getX()>axisLine.getStart().getX()){
								ecc = -ecc;
							}
						}

					}
					if(beamSeg == null){
						System.out.println(level+"-----没有对应的梁------"+JSON.toJSONString(item));
//						continue;
					}else{
						beamSeg.setLevel(Integer.parseInt(level));
						beamSeg.setEcc(ecc);
					}

//					System.out.println(item.getStart()+"---------1-------"+item.getEnd());
//					System.out.println(ecc+"--------2--------"+JSON.toJSONString(beamSeg));
					List<JointDTO> beamCrossPointArr = new ArrayList<>();
					// 标记axis是否被次梁切割
					boolean isCross = false;
					if(beamSeg !=null && beamSeg.getSpan() && !item.isSecondaryBeam() && beamCrossPointList != null && beamCrossPointList.size()>0){
						// 判断次梁对应的轴网坐标是否在axis轴上
						for(JointDTO p : beamCrossPointList){
//							System.out.println(p+"------------------"+item);
							// 判断点是否在线段树
							if(MathUtil.isInLineSegment(axisLine,new Point(p.getX(),p.getY()))){
//								System.out.println("---------1--------");
								// 说明次梁吧跨梁在盈建科中切割成两段
								isCross = true;
								beamCrossPointArr.add(p);


							}
						}
					}
					isCross = false;
					// 说明是跨梁一次或者多次被次梁切割
					if(isCross && beamCrossPointArr.size()>0){
						Collections.sort(beamCrossPointArr, new Comparator<JointDTO>() {
							@Override
							public int compare(JointDTO t1, JointDTO t2) {
								if(t1.getX()>t2.getX()){
									return 1;
								}else if (t1.getX()<t2.getX()){
									return -1;
								}else{
									if(t1.getY()>t2.getY()){
										return 1;
									}else if (t1.getY()<t2.getY()){
										return -1;
									}else{
										return 0;
									}
								}

							}
						});
						beamCrossPointArr.add(0,item.getStart());
						beamCrossPointArr.add(item.getEnd());
						for(int i = 0;i<beamCrossPointArr.size()-1;i++){
							JointDTO start = beamCrossPointArr.get(i);
							JointDTO end = beamCrossPointArr.get(i+1);
							GridDTO gridDTO1 = GridDTO.builder()
									.id(++id)
									.no(gridDTOList.size()+1)
									.level(item.getLevel())
									.start(start)
									.end(end)
									.axis(item)
									.floorDTO(floorDTO)
									.stdFlrDTO(floorDTO.getStdFlrDTO())
									.build();
							gridDTOList.add(gridDTO1);
							dbUtil.insertTblGrid(gridDTO1);
/*
							GridDTO gridDTO2 = GridDTO.builder()
									.id(++id)
									.no(gridDTOList.size()+1)
									.level(item.getLevel())
									.start(p)
									.end(item.getEnd())
									.axis(item)
									.floorDTO(floorDTO)
									.stdFlrDTO(floorDTO.getStdFlrDTO())
									.build();
							gridDTOList.add(gridDTO2);
							dbUtil.insertTblGrid(gridDTO2);*/

							// 把跨梁切割梁段
							BeamSegDTO beamSegDTO1 = new BeamSegDTO();
							BeanUtils.copyProperties(beamSeg,beamSegDTO1);
							beamSegDTO1.setId(++id);
							beamSegDTO1.setNo(++tblBeamNo);
							beamSegDTO1.setGrid(gridDTO1);
							beamSegDTO1.setFloorDTO(floorDTO);
							beamSegDTO1.setStdFlrDTO(floorDTO.getStdFlrDTO());
							dbUtil.insertTblBeamSeg(beamSegDTO1);

							/*BeamSegDTO beamSegDTO2 = new BeamSegDTO();
							BeanUtils.copyProperties(beamSeg,beamSegDTO2);
							beamSegDTO2.setId(++id);
							beamSegDTO2.setNo(++tblBeamNo);
							beamSegDTO2.setGrid(gridDTO2);
							beamSegDTO2.setFloorDTO(floorDTO);
							beamSegDTO2.setStdFlrDTO(floorDTO.getStdFlrDTO());
							dbUtil.insertTblBeamSeg(beamSegDTO2);*/
						}
					}
					if(!isCross){
						GridDTO gridDTO1 = GridDTO.builder()
								.id(++id)
								.no(gridDTOList.size()+1)
								.level(item.getLevel())
								.start(item.getStart())
								.end(item.getEnd())
								.axis(item)
								.floorDTO(floorDTO)
								.stdFlrDTO(floorDTO.getStdFlrDTO())
								.build();
						gridDTOList.add(gridDTO1);
						dbUtil.insertTblGrid(gridDTO1);

						if(beamSeg != null){
							beamSeg.setGrid(gridDTO1);
							beamSeg.setId(++id);
							beamSeg.setNo(++tblBeamNo);
							dbUtil.insertTblBeamSeg(beamSeg);
						}

					}
				}
//				System.out.println("----------------------"+JSON.toJSONString(gridDTOList));
			}

			// 计算tblGrid数据


			// 解析板数据
			System.out.println("---------开始分析板---------");
			int tblSlabSectIndex = 0;
			List<ComponentDTO> tblSlabList = result.get(ComponentCategoryEnum.FLOOR_N);
//			System.out.println("----tblSlabList----"+ JSON.toJSONString(tblSlabList));
			if(tblSlabList != null){
				for(ComponentDTO c : tblSlabList){
					// 构件定位点坐标X1
					FieldDTO field_x1 = c.getFieldDTOMap().get("DXB021");
					// 构件定位点坐标Yw
					FieldDTO field_yw = c.getFieldDTOMap().get("DXB022");
					// 构件定位点坐标z
					FieldDTO field_z = c.getFieldDTOMap().get("DXB023");
					// 方向角
					FieldDTO field_b = c.getFieldDTOMap().get("DXB024");
					// 板宽度
					FieldDTO field_w = c.getFieldDTOMap().get("DXB026");
					// 板宽度
					FieldDTO field_l = c.getFieldDTOMap().get("DXB025");
					// 板厚度
					FieldDTO field_h = c.getFieldDTOMap().get("DXB027");

					if(field_x1 != null && field_x1 != null) {
						double x = Double.parseDouble(field_x1.getValue())*1000;
						double y = Double.parseDouble(field_yw.getValue())*1000;
						double z = Double.parseDouble(field_z.getValue())*1000;
						double b = Double.parseDouble(field_b.getValue());
						double w = Double.parseDouble(field_w.getValue());
						double l = Double.parseDouble(field_l.getValue());
						double h = Double.parseDouble(field_h.getValue());

						double br = Math.toRadians(b);

						String stdFlrIDKey = String.valueOf(z+h);

						PointDTO p1 = new PointDTO();
						PointDTO p2 = new PointDTO();
						PointDTO p3 = new PointDTO();
						PointDTO p4 = new PointDTO();

						p1.setX(x+Math.sin(br)*(w/2));
						p1.setY(y-Math.cos(br)*(w/2));

						p2.setX(x+Math.cos(br)*l + Math.sin(br)*(w/2));
						p2.setY(x+Math.sin(br)*l - Math.cos(br)*(w/2));

						p3.setX(x+Math.cos(br)*l - Math.sin(br)*(w/2));
						p3.setY(x+Math.sin(br)*l + Math.cos(br)*(w/2));

						p4.setX(x-Math.sin(br)*(w/2));
						p4.setY(y+Math.cos(br)*(w/2));


						Map<String,String> tblFloorObj = tblFloor.get(stdFlrIDKey);


							String key = c.getCode();
							if(!tblSlab.containsKey(key)){
								// 处理tblColSect
								Map<String,String> obj = new HashMap<>();
								tblSlabSectIndex++;
								obj.put("ID",String.valueOf(tblSlabSectIndex));
								obj.put("No_",String.valueOf(tblSlabSectIndex));
								obj.put("StdFlrID","1");
								obj.put("GridsID","'1012,1018,1014,1020,'");
								obj.put("VertexX","'"+p1.getX()+","+p2.getX()+","+p3.getX()+","+p4.getX()+",'");
								obj.put("VertexY","'"+p1.getY()+","+p2.getY()+","+p3.getY()+","+p4.getY()+",'");
								obj.put("VertexZ","'"+p1.getZ()+","+p2.getZ()+","+p3.getZ()+","+p4.getZ()+",'");
								obj.put("RoomlsHole","0");
								obj.put("Thickness",String.valueOf(h));
								obj.put("cc","0");
								obj.put("dead","5");
								obj.put("live","2");
								obj.put("TransWay","0");
								obj.put("Ang1","0");
								obj.put("Ang2","0");
								tblSlab.put(key, obj);

								StringBuilder tblColSectSql = new StringBuilder();
								tblColSectSql.append("insert into tblSlab(ID,No_,StdFlrID,GridsID,VertexX,VertexY,VertexZ,RoomIsHole,Thickness,cc,dead,live,TransWay,Ang1,Ang2)values(")
										.append(obj.get("ID"))
										.append(",").append(obj.get("No_"))
										.append(",").append(obj.get("StdFlrID"))
										.append(",").append(obj.get("GridsID"))
										.append(",").append(obj.get("VertexX"))
										.append(",").append(obj.get("VertexY"))
										.append(",").append(obj.get("VertexZ"))
										.append(",").append(obj.get("RoomlsHole"))
										.append(",").append(obj.get("Thickness"))
										.append(",").append(obj.get("cc"))
										.append(",").append(obj.get("dead"))
										.append(",").append(obj.get("live"))
										.append(",").append(obj.get("TransWay"))
										.append(",").append(obj.get("Ang1"))
										.append(",").append(obj.get("Ang2"))
										.append(");");
								System.out.println("----------"+tblColSectSql.toString());
//								db.executeUpdateSql(tblColSectSql.toString());
							}
					}
				}
			}
			System.out.println("--------开始执行数据库--------");
			db.beginTransaction();
			String[] sqlArr = db.getSql().split(";");
			for(String s : sqlArr){
//				System.out.println(s);
				int i = db.executeUpdateNotClose(s);
				if(i==0){
					break;
				}

			}
			//		db.executeUpdateNotClose(content);
			db.commitTransaction();
			db.close();
			System.out.println("--------结束执行数据库--------");

			/*System.out.println("--------tblStdSql--------");
			System.out.println(tblStdSql.toString());
			System.out.println("--------tblFloorSql--------");
			System.out.println(tblFloorSql.toString());*/
//			System.out.println("--------sql--------"+sql.toString());
//			sql = new StringBuilder("insert into tblStdFlr(ID,NO_,height)values(3,3,3600.0);insert into tblStdFlr(ID,NO_,height)values(2,2,3600.0);");

		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static void main(String[] args) {
		String filePath = "E:\\工作\\项目\\bim\\开发\\cdm测试\\板-双柱洞口.xlsx";
		//		ExcelUtil.read(filePath);

		String srcfilePath = "E:\\工作\\项目\\bim\\开发\\F1";
		srcfilePath = "E:\\工作\\项目\\bim\\开发\\2019-12-30\\F1-2";
		srcfilePath = "E:\\工作\\项目\\bim\\开发\\2019-1-2\\汇总";
		String descFilePath = srcfilePath+File.separator+"result.ydb";
//		Map<ComponentCategoryEnum,List<ComponentDTO>> result = ExcelUtil.parse(filePath);
		convert(srcfilePath,descFilePath);

		/*ConnDB db = new ConnDB("jdbc:sqlite::resource:demo-yjk.ydb","","");
		Vector<Map<String,Object>> data = db.getData(" select name from sqlite_master where type = 'table'");
		Optional.ofNullable(data).ifPresent(t->t.forEach(item->ConvertUtil.clearTable(db,item)));*/

	}

	public static Integer getLevelByCode(String code){
		code = code.trim();
		code = code.substring(code.indexOf("-")+1);
		code = code.substring(code.indexOf("-")+1,code.lastIndexOf("-"));
		return Integer.parseInt(code);
	}

	private static void clearTable(ConnDB db,Map<String,Object> item){
		String tableName = String.valueOf(item.get("name"));
		System.out.println("delete from "+tableName+";");
		db.executeUpdateSql("delete from "+tableName);
	}
}
